#include <stdio.h>  
#include <stdlib.h>  
#include <errno.h>  
#include <string.h>  
#include <sys/types.h>  
#include <netinet/in.h>  
#include <sys/socket.h>  
#include <sys/wait.h>  
#include <unistd.h>  
#include <arpa/inet.h>  
#include <time.h>
#include <dirent.h>
#include <sqlite3.h>
#include "ds_lib_seu.h"

#define BUFFERT 1024
#define SERVERPORT 21001

int storeFeaturesInDB(sqlite3 **ppDB, DFEATURE dfeature, unsigned int timestamp, int ddosType);

int main(int argc, char **argv)  
{
    // database 部分
    sqlite3 *db = 0;
    int ret = 0;
    // open database
    ret = sqlite3_open("DDoSData.sqlite3",&db);
    if(ret != SQLITE_OK)
    {
        printf("open database error!\n");
        exit(1);
    }
    printf("database connected\n");


    // socket 部分
    int sockfd, new_fd;
    socklen_t len;  
  
    /* struct sockaddr_in my_addr, their_addr; */ // IPv4  
    struct sockaddr_in6 my_addr, their_addr; // IPv6  
  
    unsigned int lisnum = 2;  
    char buf[BUFFERT];
  
    /* if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { */ // IPv4  
    if ((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1) { // IPv6  
        perror("socket");  
        exit(1);  
    } else  
        printf("socket created\n");  
  
    bzero(&my_addr, sizeof(my_addr));  
    /* my_addr.sin_family = PF_INET; */ // IPv4  
    my_addr.sin6_family = PF_INET6;    // IPv6  
    /* my_addr.sin_port = htons(myport); */ // IPv4  
    my_addr.sin6_port = htons(SERVERPORT);   // IPv6  
    my_addr.sin6_addr = in6addr_any;     // IPv6  
 
    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in6)) == -1) {
        perror("bind");  
        exit(1);  
    } else  
        printf("binded\n");  
  
    if (listen(sockfd, lisnum) == -1) {  
        perror("listen");  
        exit(1);  
    } else  
        printf("begin listen\n");  
  
    while (1) {
        printf("\nwaiting...\n");  
        len = sizeof(struct sockaddr);  
        if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &len)) == -1) 
        {  
            perror("accept");  
            exit(errno);  
        } else
        {
            printf("server: got connection from %s, port %d, socket %d\n", 
            inet_ntop(AF_INET6, &their_addr.sin6_addr, buf, sizeof(buf)),
            their_addr.sin6_port, new_fd);
        }
             
        /* 开始处理每个新连接上的数据收发 */  
        /* 接收客户端的消息 */
        while(1)
        {
            // 首先接受长度
            bzero(buf, BUFFERT);
            if(recv(new_fd, buf, 4, 0) < 0 )
            {
                printf("Accept len error!");
            }
            int dfLen=-1;
            memcpy(&dfLen,buf,4);
            if(dfLen == -1)
            {
                break; //退出条件为：接收了-1的长度
            }
            //然后接受数据
            bzero(buf, BUFFERT);
            if(recv(new_fd, buf, dfLen, 0) < 0 )
            {
                printf("Accept data error!");
            }
            double features[11];
            int i = 0;
            for(i=0;i<11;i++)
            {
                memcpy(&features[i], buf+i*8, 8);
            }
            unsigned int timestamp;
            int ddosType;
            memcpy(&timestamp,buf+88,4);
            memcpy(&ddosType,buf+92,4);            
            DFEATURE dfeature = {
                features[0],
                features[1],
                features[2],
                features[3],
                features[4],
                features[5],
                features[6],
                features[7],
                features[8],
                features[9],
                features[10]
                };
            if(storeFeaturesInDB(&db,dfeature,timestamp,ddosType)==0)
            {
                printf("store in database OK!\n");
            }else{
                printf("store in database ERROR!\n");
            }
        }

        /* 处理每个新连接上的数据收发结束 */  
    }  
  
    close(sockfd);  
    return 0;  
} 

int storeFeaturesInDB(sqlite3 **ppDB, DFEATURE dfeature, unsigned int timestamp, int ddosType)
{
    int ret = 0;
    char *errMsg;
    char sql[1024];
    sprintf(sql,"insert into ddosFeatures values(%u,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%d)",
        timestamp,
        dfeature.protocol_type,
        dfeature.src_bytes,
        dfeature.dst_bytes,
        dfeature.flag_count,
        dfeature.src_ip_count,
        dfeature.packet_length,
        dfeature.packet_count,
        dfeature.tcp_packet_count,
        dfeature.tcp_src_port_count,
        dfeature.tcp_dst_port_count,
        dfeature.tcp_fin_flag_count,
        ddosType);

    ret = sqlite3_exec(*ppDB,sql,0,0,&errMsg);
    if (ret!=SQLITE_OK)
    {
        sqlite3_close(*ppDB);
        printf("insert error!");
    }
}
